﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using SLaB.Utilities.Xaml.Serializer.UI;
using Telerik.Windows.Controls;

namespace SilentWebsite.ViewModels
{
    public class DynamicControlManager : ViewModelBase
    {
        protected FrameworkElement selectedElement;
        protected Point lastLocation;
        protected RadContextMenu designMenu;

        public Panel LayoutRoot { get; set; }
        public bool IsElementSelected
        {
            get { return selectedElement != null; }
        }
        public FrameworkElement SelectedElement
        {
            get { return selectedElement; }
            set
            {
                selectedElement = value;
                OnPropertyChanged("SelectedElement");
            }
        }
        public FrameworkElement LastSelectedElement { get; set; }

        public DynamicControlManager(Panel layoutRoot, RadContextMenu menu)
            : base("Dynamic Control Manager")
        {
            LayoutRoot = layoutRoot;
            LayoutRoot.MouseMove += MouseMove;
            LayoutRoot.MouseLeftButtonDown += MouseLeftButtonDown;
            LayoutRoot.MouseLeftButtonUp += MouseLeftButtonUp;
            LayoutRoot.MouseRightButtonDown += MouseRightButtonDown;
            designMenu = menu;
        }

        public void AddElement(FrameworkElement element)
        {
            if (element == null)
                return;

            element.MouseLeftButtonDown += MouseLeftButtonDown;
            element.MouseLeftButtonUp += MouseLeftButtonUp;
            element.MouseRightButtonDown += MouseRightButtonDown;
            element.MouseMove += MouseMove;

            element.SetValue(Canvas.TopProperty, lastLocation.Y);
            element.SetValue(Canvas.LeftProperty, lastLocation.X);

            if (element is Border)
            {
                var border = element as Border;
                border.Child.MouseLeftButtonDown += MouseLeftButtonDown;
                border.Child.MouseLeftButtonUp += MouseLeftButtonUp;
                border.Child.MouseRightButtonDown += MouseRightButtonDown;
                border.Child.MouseMove += MouseMove;
            }

            LayoutRoot.Children.Add(element);
        }
        public void RemoveElement(FrameworkElement element)
        {
            if (element == null)
                return;

            element.MouseLeftButtonDown -= MouseLeftButtonDown;
            element.MouseLeftButtonUp -= MouseLeftButtonUp;
            element.MouseRightButtonDown -= MouseRightButtonDown;
            element.MouseMove -= MouseMove;

            if (element is Border)
            {
                var border = element as Border;
                border.Child.MouseLeftButtonDown -= MouseLeftButtonDown;
                border.Child.MouseLeftButtonUp -= MouseLeftButtonUp;
                border.Child.MouseRightButtonDown -= MouseRightButtonDown;
                border.Child.MouseMove -= MouseMove;
            }

            LayoutRoot.Children.Remove(element);
        }
        public void LoadLayout(string xaml)
        {
            var canvas = XamlReader.Load(xaml) as Canvas;
            if (canvas == null)
                return;

            foreach (var element in canvas.Children)
                LayoutRoot.Children.Add(element);
        }
        public string SaveLayout()
        {
            var serializer = new UiXamlSerializer();
            var xaml = serializer.Serialize(LayoutRoot);
            return xaml;
        }

        public void CaptureElement(FrameworkElement element)
        {
            SelectedElement = element;
            LastSelectedElement = element;
        }
        public void ReleaseElement()
        {
            selectedElement = null;
        }
        public void MoveElement(Point currentLocation)
        {
            var xShift = currentLocation.X - lastLocation.X;
            var yShift = currentLocation.Y - lastLocation.Y;
            selectedElement.SetValue(Canvas.LeftProperty, (double)selectedElement.GetValue(Canvas.LeftProperty) + xShift);
            selectedElement.SetValue(Canvas.TopProperty, (double)selectedElement.GetValue(Canvas.TopProperty) + yShift);
            lastLocation = currentLocation;
        }

        protected void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            lastLocation = e.GetPosition(LayoutRoot);
            if (selectedElement != e.OriginalSource)
                CaptureElement((FrameworkElement)e.OriginalSource);
        }
        protected void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ReleaseElement();
        }
        protected void MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            lastLocation = e.GetPosition(LayoutRoot);
            e.Handled = true;
            designMenu.IsOpen = true;
        }
        protected void MouseMove(object sender, MouseEventArgs e)
        {
            if (IsElementSelected && e.OriginalSource == selectedElement)
            {
                var currentLocation = e.GetPosition(LayoutRoot);
                MoveElement(currentLocation);
            }
        }
    }
}
